﻿#include "Limiter.h"
#include "lang/StringFormat.hpp"
using namespace yzrilyzr_lang;
using namespace yzrilyzr_util;
namespace yzrilyzr_dsp{
	Limiter::Limiter(){
		registerSub("Env", &envd);
		registerParamNormal01("Threshold", &threshold);
	}
	Limiter::Limiter(u_time_ms attackTime, u_time_ms holdTime, u_time_ms releaseTime, u_sample threshold) : Limiter(attackTime,holdTime, releaseTime, threshold, EnvelopDetector::PEAK,1){}
	Limiter::Limiter(u_time_ms attackTime, u_time_ms holdTime, u_time_ms releaseTime, u_sample threshold, u_time_ms rmsWindow) : Limiter(attackTime, holdTime, releaseTime, threshold, EnvelopDetector::RMS, rmsWindow){}
	Limiter::Limiter(u_time_ms attackTime, u_time_ms holdTime, u_time_ms releaseTime, u_sample threshold, int limitType, u_time_ms rmsWindow) :
		threshold(threshold){
		envd.attack=attackTime;
		envd.hold=holdTime;
		envd.release=releaseTime;
		envd.type=limitType;
		envd.rmsWindow=rmsWindow;		
	}
	u_sample Limiter::procDsp(u_sample v){
		//检测阈值
		envd.procDsp(v);
		u_sample env=envd.getEnvValue();
		u_sample gain=1;
		if(env > threshold){
			gain=threshold / env;
		} 
		return v * gain;
	}
	void Limiter::resetMemory(){
		envd.resetMemory();
	}
	void Limiter::cloneParam(DSP * obj1){
		if(auto other=dynamic_cast<Limiter *>(obj1)){
			envd.cloneParam(&other->envd);
			threshold=other->threshold;			
		}
	}
	std::shared_ptr<DSP> Limiter::cloneDSP(){
		return std::make_shared < Limiter>(envd.attack,envd.hold, envd.release, threshold, envd.type,envd.rmsWindow);
	}
	void Limiter::init(u_sample_rate sampleRate){
		envd.init(sampleRate);
	}
	String Limiter::toString()const{
		return StringFormat::object2string("Limiter", envd.attack, envd.hold, envd.release, threshold, envd.type, envd.rmsWindow);
	}
}